package com.ludomancy.gamelib.verlet;

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;

import com.ludomancy.gamelib.WorldScreenProjection;

public class Mesh extends VerletObject
{
	protected Vertex[] verts;
	protected Edge[] eedges;
	protected Edge[] iedges;
	private static final int VERLET_ITERATIONS = 3;
	
	public Mesh()
	{
		this.collisionType = Simulation.COLLISION_MESH;
	}
	
	public Edge[] getCollisionEdges()
	{
		return eedges;
	}
	
	public void update(Simulation s)
	{
		// integrate
		float airFrictionTerm1 = 2 - 0;
		float airFrictionTerm2 = 1 - 0;
		for (int k = 0; k < verts.length; k++)
		{
			Vertex v = verts[k];
			if(v.fixed) continue;
			// reset forces
			v.forceX = 0;
			v.forceY = s.gravity;
			
			float oldX = v.px;
			float oldY = v.py;
			
			float limit = 0.0015f;
			
			if(v.px - v.old_px > limit)
			{
				v.old_px = v.px -limit;
			}
			else
			if(v.px - v.old_px < -limit)
			{
				v.old_px = v.px + limit;
			}

			if(v.py - v.old_py > limit)
			{
				v.old_py = v.py -limit;
			}
			else
			if(v.py - v.old_py < -limit)
			{
				v.old_py = v.py + limit;
			}
			
			v.px = airFrictionTerm1 * v.px - v.old_px * airFrictionTerm2 + v.forceX;
			v.py = airFrictionTerm1 * v.py - v.old_py * airFrictionTerm2 + v.forceY;
			
			v.old_px = oldX;
			v.old_py = oldY;
		}
		
		// enforce constrains
		for (int k = 0; k < VERLET_ITERATIONS; k++)
		{
			restrictVertices();
			for (int j = 0; j < eedges.length; j++)
			{
				Edge e = eedges[j];
//				System.out.println("effort "+e.effort());
//				if(e.effort() > 1.0000001)
//				{
//					e.destroy();
//				}
//				else
				{
					e.ensureLength();
				}
			}
			for (int j = 0; j < iedges.length; j++)
			{
				Edge e = iedges[j];
				e.ensureLength();
			}
		}
	}
	
	public void paint(Graphics g, WorldScreenProjection proj)
	{
		Graphics2D g2d = (Graphics2D) g;
		g2d.setStroke(new BasicStroke(3.5f));
		for (int j = 0; j < eedges.length; j++)
		{
			Edge e = eedges[j];
			int[] segment1 = proj.worldToScreen(e.v1.px, e.v1.py);
			int[] segment2 = proj.worldToScreen(e.v2.px, e.v2.py);
			g.drawLine(segment1[0], segment1[1], segment2[0], segment2[1]);
		}	
	}
	
	protected void restrictVertices()
	{
		
	}

}
